package concurrent;

import java.util.concurrent.Callable;

public abstract class Job<E> implements Callable<E> {
	// lock
	private Lock lock = null;

	void setLock(Lock lock) {
		this.lock = lock;
	}

	public E call() throws Exception {
		E result = null;
		try {
			result = this.execute();// executechild's task
		} catch (Exception e) {
			e.printStackTrace();
		}
		// decide whether need to join the tasks
		if (lock.isJoin) {
			synchronized (lock) {
				// task finished, count down the thread numbers, and wake up the
				// main thread
				lock.thread_count--;
				lock.notifyAll();
			}
		}
		lock.semaphore.release();// release thread permission
		return result;
	}

	/**
	 * handling function
	 */
	public abstract E execute();
}
